#ifndef __CCULLTHREAD__
#define __CCULLTHREAD__

#include "CryThread.h"
#include <IJobManager.h>

struct SRenderMeshRenderInfo;
struct SRenderMeshRenderInfoModified;

namespace NAsyncCull
{



#define MAX_CAMS 4

enum ECullState
{
	ECS_WAITING							=	0,
	ECS_FINISHED						=	1,
	ECS_CHECKOCCLUSION			=	2,
	ECS_PREPAREDEPTHBUFFER	=	4,
};
class CCullThread : public Cry3DEngineBase
{
	volatile uint32														m_CullState;
	bool																			m_Enabled;

	Matrix44A																	m_MatScreenViewProj _ALIGN(16);
	Matrix44A																	m_MatScreenViewProjTransposed;
	Vec3																			m_ViewDir;
	Matrix44A																	m_Cameras[MAX_CAMS];
	int																				m_CameraID;
	Vec3																			m_Position;
	PodArray<SRenderMeshRenderInfo>*					m_parrSRenderMeshRenderList;
	PodArray<SRenderMeshRenderInfoModified>*	m_parrSRenderMeshRenderModifiedList;
	float																			m_NearPlane;
	float																			m_FarPlane;
	float																			m_NearestMax;





		void																		CalcDist(const Vec3& rViewDir,SRenderMeshRenderInfo& rRMRI)const;

		template<class T>
		ILINE	void															InitDistance(const Vec3& rViewDir,T& rRMRIArray)const
																						{
																							for(size_t a=0,S=rRMRIArray.Size();a<S;a++)
																								CalcDist(rViewDir,rRMRIArray[a]);
																						}

		void																		Prepare();
		void																		RunJob(uint32 Task, JobManager::SJobState* pJobState);

public:
	void																		CheckOcclusion(uint32 Task);
	void																			Init();


#ifndef __SPU__
																						CCullThread();
																						~CCullThread();


  bool              												HasFinished() const
                    												{
                    												  return m_CullState==ECS_FINISHED;
                    												}

	void																			PrepareCullbufferAsync(const CCamera& rCam);
	void																			CullStart( const CCamera& rCam,
																									PodArray<SRenderMeshRenderInfo>&	arrSRenderMeshRenderList,
																									PodArray<SRenderMeshRenderInfoModified>&	arrSRenderMeshRenderModifiedList);
	void																			CullWait( const CCamera& rCam,
																									PodArray<SRenderMeshRenderInfo>&	arrSRenderMeshRenderList,
																									PodArray<SRenderMeshRenderInfoModified>&	arrSRenderMeshRenderModifiedList);
#endif //__SPU__

} _ALIGN(128);

}

#endif

